

from fastapi import Request, HTTPException, Body
from configs import GO_SERVICE_SECRET_KEY, ALGORITHM
import requests
import time
import base64
import json
from server.utils import decode_verify_token
from server.utils import BaseResponse
from pprint import pprint
from loguru import logger
from configs.logging_config import configure_logging
from sse_starlette.sse import EventSourceResponse

configure_logging()


async def generate_audio(
    tts_text: str = Body(..., description="需要合成的文本"),
    voice_id: str = Body(..., description="请求的音色编号"),
    model: str = Body("speech-02-hd", description="语音模型:speech-02-hd/speech-02-turbo/speech-01-turbo/speech-01-hd"),
    output_format: str = Body("hex", description="输出格式:hex/url(url格式仅在非流式场景生效且只能生效24小时)"),
    stream: bool = Body(False, description="是否流式输出:true/false"),
    language_boost: str = Body("auto", description="语言增强"),
    speed: float = Body(1.0, description="生成声音的语速:0.5-2"),
    vol: float = Body(1.0, description="生成声音的音量:0-10"),
    pitch: int = Body(0, description="生成声音的语调:-12-12"),
    emotion: str = Body("happy", description="控制合成语音的情绪:happy/sad/angry/fearful/disgusted/surprised/neutral"),
    sample_rate: int = Body(32000, description="生成声音的采样率:8000/16000/22050/24000/32000/44100"),
    bitrate: int = Body(128000, description="生成声音的比特率:32000/64000/128000/256000"),
    format: str = Body("mp3", description="生成的音频格式:wav/mp3/pcm/flac"),
    request: Request = None
):
    try:
        token = decode_verify_token(request, GO_SERVICE_SECRET_KEY, ALGORITHM)
    except Exception as e:
        return BaseResponse(code=401, msg="Token is invalid", data={"error": str(e.detail.get('msg'))})
    
     # 灵萌的group_id
    group_id = '1934548297561678072'
    # 灵萌的key
    api_key = 'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJHcm91cE5hbWUiOiLlub_kuJzml6DmiJHmlbDlrZfnp5HmioDmnInpmZDlhazlj7giLCJVc2VyTmFtZSI6ImhhbnNodWFuZyIsIkFjY291bnQiOiJoYW5zaHVhbmdAMTkzNDU0ODI5NzU2MTY3ODA3MiIsIlN1YmplY3RJRCI6IjE5MjUxMjMyMDMxNjkwMDE1NzAiLCJQaG9uZSI6IiIsIkdyb3VwSUQiOiIxOTM0NTQ4Mjk3NTYxNjc4MDcyIiwiUGFnZU5hbWUiOiIiLCJNYWlsIjoiIiwiQ3JlYXRlVGltZSI6IjIwMjUtMDYtMTcgMTY6MjI6MTYiLCJUb2tlblR5cGUiOjEsImlzcyI6Im1pbmltYXgifQ.f8xXTzVMIjyi1ZJfuIROeIQyef1qTrOeSpEKhzsqx1H9K15my3UrUbZTAu45qegzOFM5YegvWliCLG1oRLkEuyYkgBOPm1eLAdDWCMfLB931UE1OaVk_bYsqLdV7f2MwaR_oAVkUVFaPTEX4XF-bwvbe0kVeIyYRH7aE1g_tXdUH34mRFLXEwibHhQEMilkdrk3LEa7bWIJV6zYGeIkG4x7azsSoimYPz7NHuPou7CP4sWwLuF8rECJjj30ie5kxSbovG3fRfaeHXYISULJhhBH8Jy343jwbGp4c3S7iggMp_d0EqqRGm-CVHomfg7zdxp8QDVyr2YB3SfRbR0mPUA'  # 您的MiniMax API Key

    url = f"https://api.minimaxi.com/v1/t2a_v2?GroupId={group_id}"
    headers = {"Content-Type": "application/json", "Authorization": f"Bearer {api_key}"}
    
    try:
        body = {
        "model": model,
        "text": tts_text, # 待合成的文本，长度限制<10000字符，段落切换用换行符替代。（如需要控制语音中间隔时间，在字间增加<#x#>,x单位为秒，支持0.01-99.99，最多两位小数）。支持自定义文本与文本之间的语音时间间隔，以实现自定义文本语音停顿时间的效果。需要注意的是文本间隔时间需设置在两个可以语音发音的文本之间，且不能设置多个连续的时间间隔。
        "stream": stream, # 是否流式。默认false，即不开启流式。
        "output_format": output_format, # 控制输出结果形式的参数。可选值为url/hex。默认值为hex。该参数仅在非流式场景生效，流式场景仅支持返回hex形式。返回的url有效期为24小时。
        "voice_setting":{ 
            "voice_id": voice_id, # 请求的音色编号。支持系统音色(id)以及复刻音色（id）两种类型，
            "speed": speed, # 生成声音的语速，可选，取值越大，语速越快。范围[0.5,2]，默认值为1.0
            "vol": vol, # 范围（0,10]，默认值为1.0 生成声音的音量，可选，取值越大，音量越高。
            "pitch": pitch, # 范围[-12,12]，默认值为0 生成声音的语调，可选，（0为原音色输出，取值需为整数）。
            "emotion": emotion # 控制合成语音的情绪；当前支持7种情绪：高兴，悲伤，愤怒，害怕，厌恶，惊讶，中性；参数范围["happy", "sad", "angry", "fearful", "disgusted", "surprised", "neutral"]
            # emotion该参数仅对speech-02-hd，speech-02-turbo，speech-01-turbo，speech-01-hd生效
        },
        "audio_setting":{
            "sample_rate": sample_rate, # 范围【8000，16000，22050，24000，32000，44100】生成声音的采样率。可选，默认为32000。
            "bitrate": bitrate, # 范围【32000，64000，128000，256000】生成声音的比特率。可选，默认值为128000。该参数仅对mp3格式的音频生效。
            "format": format # 生成的音频格式。默认mp3，范围[mp3,pcm,flac,wav]。wav仅在非流式输出下支持。
        },
        "language_boost": language_boost, # 默认为null 增强对指定的小语种和方言的识别能力，设置后可以提升在指定小语种/方言场景下的语音表现。如果不明确小语种类型，则可以选择"auto"，模型将自主判断小语种类型。支持以下取值：
        # 'Chinese', 'Chinese,Yue', 'English', 'Arabic', 'Russian', 'Spanish', 'French', 'Portuguese', 'German', 'Turkish', 'Dutch', 'Ukrainian', 'Vietnamese', 'Indonesian', 'Japanese', 'Italian', 'Korean', 'Thai', 'Polish', 'Romanian', 'Greek', 'Czech', 'Finnish', 'Hindi', 'auto'
        }

        response = requests.post(url, headers=headers, json=body, stream=stream)
        
        async def get_tts_stream():
            for chunk in response.iter_lines():
                if chunk and chunk.startswith(b'data:'):
                    data = json.loads(chunk[5:])
                    if "data" in data and "extra_info" not in data:
                        if "audio" in data["data"]:
                            # 得到hex音频数据
                            hex_audio = data["data"]["audio"]
                            # 将hex转换为bytes
                            audio_bytes = bytes.fromhex(hex_audio)
                            # 转换为Base64编码
                            base64_audio = base64.b64encode(audio_bytes).decode('utf-8')
                            # 本地会话的ID
                            trace_id = data["trace_id"]
                            yield {"event": "audio",
                                    "data": {"status_code": 200, "isFinish": False, "audio_data": base64_audio,
                                            "trace_id": trace_id, "sample_rate": sample_rate, "format": format}}
                    if "extra_info" in data and "data" in data:
                        # 得到hex音频数据
                        hex_audio = data["data"]["audio"]
                        # 将hex转换为bytes
                        audio_bytes = bytes.fromhex(hex_audio)
                        # 转换为Base64编码
                        full_base64_audio = base64.b64encode(audio_bytes).decode('utf-8')
                        # 本地会话的ID
                        trace_id = data["trace_id"]
                        yield {"event": "audio",
                                "data": {"status_code": 200, "isFinish": True, "audio_data": full_base64_audio,
                                "trace_id": trace_id, "sample_rate": sample_rate, "format": format}}
                
        if stream:
            return EventSourceResponse(get_tts_stream(), media_type="text/event-stream")
        else:
            response.raise_for_status()
            response_json = response.json()
            if response_json["base_resp"]["status_code"] != 0:
                logger.error(response_json)
                raise HTTPException(status_code=500, detail=response_json["base_resp"]["status_msg"])
            else:
                # 将hex转换为bytes
                audio_bytes = bytes.fromhex(response_json["data"]["audio"])
                
                # 转换为Base64编码
                full_audio_base64 = base64.b64encode(audio_bytes).decode('utf-8')
                
                # return {
                #     "status_code": 200,
                #     "isFinish": True,
                #     "trace_id": response_json["trace_id"],
                #     "audio_data": full_audio_base64,
                #     "sample_rate": sample_rate,
                #     "format": format
                # }
                return BaseResponse(code=200, msg="success", data={"isFinish": True, "trace_id": response_json["trace_id"], "audio_data": full_audio_base64,"sample_rate": sample_rate,"format": format})

    except Exception as e:
        # raise HTTPException(status_code=500, detail=str(e))
        return BaseResponse(code=500, msg=str(e), data=None)